﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Threading;
using System.Xml;
using System.Xml.Linq;

namespace ThePingMaster
{
    public partial class ThePingMasterService : ServiceBase
    {
        private readonly ManualResetEvent _terminationEvent = new ManualResetEvent(false);
        private readonly ILogger _logger;

        public ThePingMasterService()
        {
            InitializeComponent();
            _logger = new Log4NetLogger();
#if DEBUGSERVICEASEXE
            OnStart(null);
#endif
        }        

        protected override void OnStart(string[] args)
        {            
            _logger.Info("Service starting up");

            var configFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationManager.AppSettings["configFile"]);
            if (!File.Exists(configFilename))
            {
                _logger.Error(String.Format(@"Configuration file cannot be found at {0}", configFilename));
                return;
            }

            XDocument document;
            using (XmlTextReader reader = new XmlTextReader(configFilename))
            {
                document = XDocument.Load(reader);
            }

            var addressElements = document.Root.Elements(XName.Get("address"));

            ConfigurationSettings settings = new ConfigurationSettings
                                                 {
                                                     Addresses = addressElements.Select(addressElement => addressElement.Value).ToList(),
                                                     FailureCommand = document.Root.Attribute("onFailure").Value.Trim(),
                                                     FailureCommandParams =
                                                         document.Root.Attribute("onFailureParams").Value,
                                                     Interval = int.Parse(document.Root.Attribute("interval").Value),
                                                     RetryAttemptsBeforeFailure =
                                                         int.Parse(
                                                             document.Root.Attribute("retryAttemptsBeforeFailure").Value),
                                                     SuccessCommand = document.Root.Attribute("onSuccess").Value.Trim(),
                                                     SuccessCommandParams =
                                                         document.Root.Attribute("onSuccessParams").Value,
                                                     Timeout = int.Parse(document.Root.Attribute("timeout").Value),
                                                     RetryOnNetworkException = bool.Parse(document.Root.Attribute("retryOnNetworkException").Value)
                                                 };

            var pingExecuter = new PingExecuter(
                _logger,
                settings,
                new PingSender(settings.Timeout), 
                new CommandExecuter(_logger), 
                _terminationEvent);

            new Thread(pingExecuter.Start).Start();
#if DEBUGSERVICEASEXE
            Thread.Sleep(50000);
#endif
        }

        protected override void OnStop()
        {
            _logger.Info("Service stopping");
            _terminationEvent.Set();
        }
    }
}
